package org.csu.small.controller.front;

import com.alipay.api.AlipayApiException;
import com.alipay.api.internal.util.AlipaySignature;
import com.beust.jcommander.internal.Maps;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.csu.small.common.Constant;
import org.csu.small.common.ResponseCode;
import org.csu.small.common.UniformResponse;
import org.csu.small.configuration.AlipayConfig;
import org.csu.small.entity.User;
import org.csu.small.service.IOrderService;
import org.csu.small.vo.OrderVo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.util.Iterator;
import java.util.Map;

/**
 * @author SongYaolun
 * @version 1.0
 * @date 2020/6/27 10:48
 */
@Controller
@RequestMapping("/order/")
@Api(value = "OrderController", description = "前台订单接口详情")
public class OrderController {

    private static final Logger logger = LoggerFactory.getLogger(OrderController.class);

    @Autowired
    private IOrderService orderService;


    @PostMapping("create")
    @ResponseBody
    @ApiOperation(value = "前台创建新的订单")
    public UniformResponse<OrderVo> createOrder(HttpSession session, Integer shippingId){

        User user = (User) session.getAttribute(Constant.LOGIN_USER);
        if(user == null){
            return UniformResponse.createForErrorCodeMessage(ResponseCode.NEED_LOGIN.getCode(),ResponseCode.NEED_LOGIN.getDescription());
        }
        return orderService.createOrder(user.getId(),shippingId);
    }

    @GetMapping("detail")
    @ResponseBody
    @ApiOperation(value = "前台获取订单详情")
    public UniformResponse<OrderVo> getOrderDetail(BigInteger orderNo){
        return orderService.getOrderDetail(orderNo);
    }

    @PostMapping("confirm")
    @ResponseBody
    @ApiOperation(value = "前台确认收货")
    public UniformResponse<String> confirm(BigInteger orderNo){
        return orderService.confirm(orderNo);
    }

    @PostMapping("cancel")
    @ResponseBody
    @ApiOperation(value = "前台取消订单")
    public UniformResponse<String> cancel(BigInteger orderNo){
        return orderService.cancel(orderNo);
    }

    @GetMapping("list")
    @ResponseBody
    @ApiOperation(value = "前台获取订单列表")
    public UniformResponse list(
            HttpSession session,
            @RequestParam(name = "current", defaultValue = "1") int current,
            @RequestParam(name = "size" , defaultValue = "5") int size)
    {
        User user = (User) session.getAttribute(Constant.LOGIN_USER);
        if(user == null){
            return UniformResponse.createForErrorCodeMessage(ResponseCode.NEED_LOGIN.getCode(),ResponseCode.NEED_LOGIN.getDescription());
        }
        return orderService.getUserOrderList(user.getId(),current,size);
    }

    @GetMapping("search")
    @ResponseBody
    @ApiOperation(value = "前台用户查询")
    public UniformResponse search(
            @RequestParam(name = "orderNo", defaultValue = "",required = false) BigInteger orderNo,
            @RequestParam(name = "productName", defaultValue = "",required = false) String productName,
            @RequestParam(name = "current", defaultValue = "1") int current,
            @RequestParam(name = "size" , defaultValue = "5") int size,
            @RequestParam(name = "status" , defaultValue = "",required = false) int status)
    {

        return orderService.getOrderSearch(orderNo,productName,current,size,status);
    }

    @PostMapping("pay")
    @ApiOperation(value = "订单支付")
    @ResponseBody
    public UniformResponse pay(HttpServletResponse response, HttpServletRequest request, BigInteger orderNo) throws UnsupportedEncodingException {
        String path = request.getSession().getServletContext().getRealPath("upload");
        return orderService.pay(orderNo,path);

    }

    @RequestMapping(value = "pay_back",method = RequestMethod.POST)
    @ApiOperation(value = "支付回调")
    @ResponseBody
    public Object alipayCallback(HttpServletRequest request) {
        Map<String, String> params = Maps.newHashMap();

        Map requestParams = request.getParameterMap();
        //使用迭代器循环
        for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext(); ) {
            String name = (String) iter.next();
            String[] values = (String[]) requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                /**
                 * 注意细节：这里使用三目运算符，判断如果只有一个元素i=0时，直接拿空串拼上value，否则即表示多个，需要value后需要拼接一个"，"逗号
                 */
                valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
            }
            params.put(name, valueStr);
        }
        logger.info("支付宝回调,sign:{},trade_status:{},参数:{}", params.get("sign"), params.get("trade_status"), params.toString());

        /**
         * *******下面的非常重要,验证回调的正确性,是不是支付宝发的.并且呢还要避免重复通知.*********
         */
        params.remove("sign_type");

        try {
            boolean alipayRSACheckedV2 = AlipaySignature.rsaCheckV2(params, AlipayConfig.alipay_public_key, "utf-8", AlipayConfig.sign_type);

            if (!alipayRSACheckedV2) {
                return UniformResponse.createForErrorMessage("非法请求,验证不通过,再恶意请求我就报警找网警了");
            }
        } catch (AlipayApiException e) {
            logger.error("支付宝验证回调异常", e);
        }

        //TODO 根据支付宝第五步：需要严格按照如下描述校验通知数据的正确性，验证各种数据的正确性，自行添加到Service里如下面的一样，务必添加！！

        //接下来在OrderServiceImpl.java中写我们，处理阿里回调的一个业务逻辑、处理状态、是否支付过等逻辑
        UniformResponse uniformResponse = orderService.aliCallback(params);
        //如果成功直接返回
        if (uniformResponse.isSuccess()) {
            return Constant.AlipayCallback.RESPONSE_SUCCESS;
        }
        return Constant.AlipayCallback.RESPONSE_FAILED;
    }

    @PostMapping("query_order_pay_status")
    @ResponseBody
    public UniformResponse<Boolean> queryOrderPayStatus(HttpSession session, BigInteger orderNo) {

        UniformResponse serverResponse = orderService.queryOrderPayStatus(orderNo);
        if (serverResponse.isSuccess()) {
            return UniformResponse.createForSuccess(true);
        }
        return UniformResponse.createForSuccess(false);
    }

    @GetMapping("get_order_cart_product")
    @ResponseBody
    public UniformResponse getOrderCartProduct(HttpSession session) {
        User user = (User) session.getAttribute(Constant.LOGIN_USER);
        if(user == null){
            return UniformResponse.createForErrorCodeMessage(ResponseCode.NEED_LOGIN.getCode(),ResponseCode.NEED_LOGIN.getDescription());
        }
        return orderService.getOrderCartProduct(user.getId());
    }

//    @PostMapping("refund")
//    @ResponseBody
//    public UniformResponse<LocalDateTime> refund(BigInteger orderNo){
//        return orderService.refund(orderNo);
//    }


//    @PostMapping("delete")
//    @ResponseBody
//    public UniformResponse<String> delete(BigInteger orderNo){
//        return orderService.delete(orderNo);
//    }

}
